import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * @param <T> 当前类是泛型类，此时的 T 是一个占位符
 *       ！！ 1.不能实例化泛型数组
 */
class MyArray< T/* extends Number */> {
    //      Number为泛型的上界，没写 extends 则上界为 Object
    //      表示 T 只能是 Number 或者其子类，例如可以传入 Float Integer，不能传 String
    public T[] objects = (T[])new Object[10];

    public T get(int pos) {
        return objects[pos];
    }
    public void set(int pos,T val) {
        objects[pos] = val;
    }
}
class Alg<T extends Comparable<T>>{
    //      代表传入的 T 实现了 Comparable 接口
    public T findMax(T[] arr){
        T max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (max.compareTo(arr[i]) < 0){
                max = arr[i];
            }
        }
        return max;
    }
}
class Alg2{
    //      代表传入的 T 实现了 Comparable 接口
    public static<T extends Comparable<T>> T findMax(T[] arr){
        T max = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (max.compareTo(arr[i]) < 0){
                max = arr[i];
            }
        }
        return max;
    }
}
class Alg3{
    public static <T> void print(ArrayList<T> list){
        //                   知道 ArrayList 中的 T 是什么类型
        for (T t:list) {
            System.out.print(t + " ");
        }
    }
    public static void print2(ArrayList<?> list){
        //                 不知道 ArrayList 中传入的是什么类型
        for (Object t:list) {
            System.out.print(t + " ");
        }
    }
}

class A{}
class Person extends A{}
class Student extends Person{}
class C extends Student{}
public class TestDemo {
    public static void main(String[] args) {
        ArrayList<? super Person> list = new ArrayList<Person>();
        // ArrayList<? super Person> list2 = new ArrayList<Student>();
        list.add(new Person());
        list.add(new Student());
        list.add(new C());
        ArrayList<? super Person> list2 = new ArrayList<A>();
        list2.add(new Person());
        list2.add(new Student());

        Person person = (Person)list.get(0);
    }

    public static void main5(String[] args) {
        ArrayList<Integer> arrayList1 = new ArrayList<>();
        ArrayList<Double> arrayList2 = new ArrayList<>();
        List<? extends Number> list = arrayList1;
        List<? extends Number> list2 = arrayList2;
        // list.add(0,1);// 通配符的上界不适合写入数据
        // list2.add(0,10.5);
        // 此时list可以引用的子类对象很多，编译器无法确定是哪个
        Number n = list.get(0);
        // Integer i = list.get(0); // 错
    }

    public static void main4(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        Alg3.print(list);
        System.out.println("\n=====");
        Alg3.print2(list);
    }

    public static void main3(String[] args) {
        Alg<Integer> alg = new Alg();
        Integer[] arr = {1,2,3,5,3,8,6,88,99};
        System.out.println(alg.<Integer>findMax(arr));// <Integer> 可省略，可以自动识别

        System.out.println("============");

        System.out.println(Alg2.findMax(arr));
    }

    public static void main2(String[] args) {
        MyArray<String> myArray = new MyArray();
        myArray.set(0,"haha~");

        MyArray<Integer> myArrayI = new MyArray();
        myArrayI.set(0,12);
        MyArray<Number> myArrayN = new MyArray();
        myArrayN.set(0,13);
        myArrayN.set(1,12.4);
//        myArray.set(1,12); 自动进行类型的检查，这里报错
        String s = myArray.get(0);// 不需要强制类型转换，编译器自动进行转换
    }

    public static void main1(String[] args) {
        MyArray myArray = new MyArray();
        myArray.set(0,"haha~");
        myArray.set(1,12);
        String s = (String)myArray.get(0);
    }
}